package com.example.demo.service;

import com.example.demo.mapper.CategoryMapper;
import com.example.demo.mapper.ProductMapper;
import com.example.demo.model.Category;
import com.example.demo.vo.ProductVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private ProductMapper productMapper;

    public List<Category> getCategoriesByLevel(Integer level) {
        return categoryMapper.getCategoriesByLevel(level);
    }

    public List<Category> getChildCategories(Integer parentId) {
        return categoryMapper.getChildCategories(parentId);
    }

    public List<Category> getCategoryTree() {
        // 获取一级分类
        List<Category> level1Categories = categoryMapper.getCategoriesByLevel(1);
        
        // 递归获取子分类
        for (Category category : level1Categories) {
            category.setChildren(getChildrenRecursively(category.getId()));
        }
        
        return level1Categories;
    }

    private List<Category> getChildrenRecursively(Integer parentId) {
        List<Category> children = categoryMapper.getChildCategories(parentId);
        if (children != null && !children.isEmpty()) {
            for (Category child : children) {
                child.setChildren(getChildrenRecursively(child.getId()));
            }
        }
        return children;
    }

    // 搜索
    public Map<String, Object> searchCategoriesWithDetails(String keyword, Integer page, Integer pageSize, String sort) {
        // 1. 参数预处理
        final String searchKeyword = keyword.trim();
        page = (page == null || page < 1) ? 1 : page;
        pageSize = (pageSize == null || pageSize < 1) ? 10 : pageSize;
        sort = (sort == null) ? "relevance" : sort.toLowerCase();

        // 2. 搜索分类
        List<Category> categories = categoryMapper.searchCategories(searchKeyword);
        
        // 3. 构建丰富的搜索结果
        List<Map<String, Object>> enrichedResults = categories.stream()
            .map(category -> enrichCategoryResult(category, searchKeyword))
            .collect(Collectors.toList());
        
        // 4. 排序结果
        sortSearchResults(enrichedResults, sort);
        
        // 5. 收集所有分类路径
        List<String> categoryPaths = enrichedResults.stream()
            .map(result -> (String) result.get("categoryPath"))
            .collect(Collectors.toList());

        // 6. 查询商品信息
        Map<String, Object> params = new HashMap<>();
        params.put("categoryPathsStr", String.join(",", categoryPaths));
        params.put("sort", sort);
        List<ProductVO> products = productMapper.getProductsByCategorySearch(params);
        
        // 7. 分页处理
        int total = products.size();
        int start = (page - 1) * pageSize;
        int end = Math.min(start + pageSize, total);
        
        List<ProductVO> pagedProducts = 
            start < total ? products.subList(start, end) : new ArrayList<>();
        
        // 8. 构建返回结果
        Map<String, Object> response = new HashMap<>();
        response.put("categories", enrichedResults);  // 分类信息
        response.put("products", pagedProducts);     // 商品信息
        response.put("total", total);
        response.put("page", page);
        response.put("pageSize", pageSize);
        response.put("totalPages", (total + pageSize - 1) / pageSize);
        
        // 9. 添加搜索建议（如果没有结果）
        if (total == 0) {
            response.put("suggestions", generateSearchSuggestions(searchKeyword));
        }
        
        return response;
    }

    /**
     * 丰富分类搜索结果
     */
    private Map<String, Object> enrichCategoryResult(Category category, String keyword) {
        Map<String, Object> result = new HashMap<>();
        result.put("category", category);
        
        // 获取完整分类路径
        List<Category> path = getCategoryPath(category.getId());
        result.put("path", path);
        
        // 构建分类路径
        String categoryPath = buildCategoryPath(path, false);
        String categoryPathName = buildCategoryPath(path, true);
        result.put("categoryPath", categoryPath);
        result.put("categoryPathName", categoryPathName);
        
        // 如果是父分类，获取子分类信息
        if (category.getLevel() < 3) {
            List<Category> children = getChildCategories(category.getId());
            result.put("children", children);
            
            // 添加子分类路径
            List<String> childPaths = children.stream()
                .map(child -> categoryPath + "." + child.getId())
                .collect(Collectors.toList());
            result.put("childPaths", childPaths);
        }
        
        // 计算相关度分数
        result.put("relevanceScore", calculateRelevanceScore(category, keyword));
        
        return result;
    }

    /**
     * 构建分类路径
     */
    private String buildCategoryPath(List<Category> path, boolean useName) {
        return path.stream()
            .map(category -> useName ? category.getName() : category.getId().toString())
            .collect(Collectors.joining(useName ? " > " : "."));
    }

    /**
     * 计算分类与搜索关键词的相关度分数
     */
    private int calculateRelevanceScore(Category category, String keyword) {
        int score = 0;
        String lowerKeyword = keyword.toLowerCase();
        
        // 名称完全匹配
        if (category.getName().toLowerCase().equals(lowerKeyword)) {
            score += 100;
        }
        // 名称包含关键词
        else if (category.getName().toLowerCase().contains(lowerKeyword)) {
            score += 50;
        }
        
        // 关键词匹配
        if (category.getKeywords() != null) {
            String[] keywords = category.getKeywords().toLowerCase().split(",");
            for (String kw : keywords) {
                if (kw.trim().equals(lowerKeyword)) {
                    score += 30;
                } else if (kw.trim().contains(lowerKeyword)) {
                    score += 10;
                }
            }
        }
        
        // 考虑分类层级
        score += (3 - category.getLevel()) * 5;
        
        return score;
    }

    /**
     * 排序搜索结果
     */
    private void sortSearchResults(List<Map<String, Object>> results, String sort) {
        switch (sort) {
            case "relevance":
                results.sort((a, b) -> ((Integer) b.get("relevanceScore"))
                    .compareTo((Integer) a.get("relevanceScore")));
                break;
            case "name":
                results.sort((a, b) -> ((Category) a.get("category")).getName()
                    .compareTo(((Category) b.get("category")).getName()));
                break;
            case "level":
                results.sort((a, b) -> ((Category) a.get("category")).getLevel()
                    .compareTo(((Category) b.get("category")).getLevel()));
                break;
            default:
                // 默认按相关度排序
                results.sort((a, b) -> ((Integer) b.get("relevanceScore"))
                    .compareTo((Integer) a.get("relevanceScore")));
        }
    }

    /**
     * 生成搜索建议
     */
    private List<String> generateSearchSuggestions(String keyword) {
        List<String> suggestions = new ArrayList<>();
        
        // 1. 尝试模糊匹配
        List<Category> fuzzyMatches = categoryMapper.searchCategories("%" + keyword + "%");
        if (!fuzzyMatches.isEmpty()) {
            fuzzyMatches.stream()
                .limit(3)
                .forEach(c -> suggestions.add("试试搜索：" + c.getName()));
        }
        
        // 2. 添加热门分类建议
        List<Category> hotCategories = getHotCategories();
        if (!hotCategories.isEmpty()) {
            suggestions.add("热门分类：" + 
                hotCategories.stream()
                    .limit(3)
                    .map(Category::getName)
                    .collect(Collectors.joining("、")));
        }
        
        return suggestions;
    }

    public List<Category> getCategoryPath(Integer categoryId) {
        List<Category> path = new ArrayList<>();
        Category current = categoryMapper.getCategoryById(categoryId);
        
        while (current != null) {
            path.add(0, current); // 添加到列表开头
            if (current.getParentId() == 0) {
                break;
            }
            current = categoryMapper.getCategoryById(current.getParentId());
        }
        
        return path;
    }

    public List<Category> getHotCategories() {
        return categoryMapper.getHotCategories();
    }

    public Category getCategoryById(Integer id) {
        return categoryMapper.getCategoryById(id);
    }
}